#ifndef AVLIST_H
#define AVLIST_H
#include <mutex>
#include <memory>

//模板
template<typename T>
class AVList
{
public:
    AVList() : head_(nullptr),tail_(nullptr),size_(0){}
    ~AVList(){}
    void push(const T& value)
    {
        //加锁，避免线程冲突
        std::unique_lock<std::mutex> lock(mutex_);
        //创建一个结点
        Node* node = new Node(value);
        if(tail_)
        {
            tail_->next = node;
            node->prev = tail_;
            tail_ = node;
        }
        else//当前没有数据
        {
            head_ = tail_ = node;
        }
        ++size_;//数量增一
    }
    //出队列
    bool pop(T& value)
    {
        //加锁，避免线程冲突
        std::unique_lock<std::mutex> lock(mutex_);
        if(!head_)
        {
            //当前没有数据
            return false;
        }
        Node* node = head_;
        value = node->value;
        //将头结点移除
        head_ = head_->next;
        if(head_)
        {
            head_->prev = nullptr;
        }
        else
        {
            tail_ = nullptr;
        }
        delete node;
        --size_;
        return true;
    }
    //释放资源
    void clear()
    {
        //加锁，避免线程冲突
        std::unique_lock<std::mutex> lock(mutex_);
        Node* node = head_;
        while(node)
        {
            Node* next = node->next;
            delete node;
            node = next;
        }
        head_ = tail_ = nullptr;
        size_ = 0;
    }
    //判断队列是否为空
    bool empty()
    {
        //加锁，避免线程冲突
        std::unique_lock<std::mutex> lock(mutex_);
        return size_ == 0;
    }
    //队列大小
    int size()
    {
        //加锁，避免线程冲突
        std::unique_lock<std::mutex> lock(mutex_);
        return size_;
    }
protected:
    struct Node
    {
        T value;
        Node* prev;
        Node* next;
        Node(const T& v) : value(v),prev(nullptr),next(nullptr){}
    };
private:
    int size_;
    Node* head_;
    Node* tail_;
    mutable std::mutex mutex_;
};

template<typename T>
class AVQueue
{
public:
    AVQueue(){}
    ~AVQueue(){clear();}
    void push(T packet)
    {
        queue_.push(packet);
    }
    bool pop(T& packet)
    {
        return queue_.pop(packet);
    }
    bool empty()
    {
        return queue_.empty();
    }
    int size()
    {
        return queue_.size();
    }
    void clear()
    {
        queue_.clear();
    }
private:
    AVList<T> queue_;
};








#endif // AVLIST_H
